package org.voidness.oje2d.gui;

import org.voidness.oje2d.GLColor;
import org.voidness.oje2d.GLFont;
import org.voidness.oje2d.GLImage;

/** A vertical progress bar widget to use with the GUI engine. */
public class VerticalProgressBar extends Widget {
    /** The top part image index */
    public static final int TOP = 0;

    /** The bar's body (empty) image index */
    public static final int BODY_EMPTY = 1;

    /** The bar's body (full) image index */
    public static final int BODY_FULL = 2;

    /** The bar's bottom part image index */
    public static final int BOTTOM = 3;

    /** The progress bar's images */
    private GLImage[] images = null;

    /** The minimum value */
    private int minimumValue;

    /** The maximum value */
    private int maximumValue;

    /** The current value for the bar */
    private int currentValue;

    /** The font to use when drawing the value */
    private GLFont font = null;

    /**
     * Default constructor
     * 
     * @param mWidth The bar's width
     * @param mHeight The bar's height
     */
    public VerticalProgressBar(int mWidth, int mHeight) {
        // Call the widget's constructor
        super(mWidth, mHeight);

        // Set this widget in 0,0 relative to it's parent
        xPos = 0;
        yPos = 0;
    }

    /**
     * Another constructor. This defines the bar's position
     * 
     * @param mX The X component of the bar's location
     * @param mY The Y component of the bar's location
     * @param mWidth The bar's width
     * @param mHeight The bar's height
     */
    public VerticalProgressBar(int mX, int mY, int mWidth, int mHeight) {
        super(mX, mY, mWidth, mHeight);
    }

    /**
     * (Re)defines the minimum value
     * 
     * @param mMinimum The value to set
     */
    public void setMinimumValue(int mMinimum) {
        minimumValue = mMinimum;
    }

    /**
     * (Re)defines the maximum value
     * 
     * @param mMaximum The value to set
     */
    public void setMaximumValue(int mMaximum) {
        maximumValue = mMaximum;
    }

    /**
     * (Re)defines the current value. Also stretches the body full image to
     * match the new current size
     * 
     * @param mCurrent The value to set
     */
    public void setCurrentValue(int mCurrent) {
        if (images[BODY_FULL] == null)
            return;

        if (mCurrent < minimumValue || mCurrent > maximumValue)
            return;

        currentValue = mCurrent;

        int maxHeight =
                height - (images[TOP].getHeight() + images[BOTTOM].getHeight());
        int newHeight =
                (int) ((float) maxHeight * (float) currentValue / (float) (maximumValue - minimumValue));

        images[BODY_FULL].setHeight(newHeight);
    }

    /**
     * Returns the minimum value
     * 
     * @return The bar's minimum value
     */
    public int getMinimumValue() {
        return minimumValue;
    }

    /**
     * Returns the maximum value
     * 
     * @return The bar's maximum value
     */
    public int getMaximumValue() {
        return maximumValue;
    }

    /**
     * Returns the current value
     * 
     * @return The bar's current value
     */
    public int getCurrentValue() {
        return currentValue;
    }

    /**
     * (Re)defines the bar's images
     * 
     * @param mImages The images to set
     * @param mFont The font to use for the value
     */
    public void setImages(GLImage[] mImages, GLFont mFont) {
        images = mImages;
        font = mFont;
    }

    /**
     * (Re)defines the bar's colors
     * 
     * @param mTopColor The color for the top image
     * @param mEmptyColor The color for the empty body image
     * @param mFullColor The color for the full body image
     * @param mBottomColor The color for the bottom image
     */
    public void setColor(GLColor mTopColor, GLColor mEmptyColor,
            GLColor mFullColor, GLColor mBottomColor) {
        // Check if all images are good
        if (images[TOP] == null || images[BODY_EMPTY] == null
                || images[BODY_FULL] == null || images[BOTTOM] == null)
            return;

        images[TOP].setColor(mTopColor);
        images[BODY_EMPTY].setColor(mEmptyColor);
        images[BODY_FULL].setColor(mFullColor);
        images[BOTTOM].setColor(mBottomColor);
    }

    /**
     * Draws the widget and all sub-widgets.
     */
    public void draw(GLColor mColor) {
        // Check if all images are good
        if (images[TOP] == null || images[BODY_EMPTY] == null
                || images[BODY_FULL] == null || images[BOTTOM] == null)
            return;

        // Draw only if visible
        if (!visible)
            return;

        int drawX = xPos + parent.getXPos();
        int drawY = yPos + parent.getYPos();

        images[TOP].draw(drawX, drawY);
        drawY += images[TOP].getHeight();
        images[BODY_EMPTY].draw(drawX, drawY);
        drawY += images[BODY_EMPTY].getHeight();
        images[BODY_FULL].draw(drawX, drawY - images[BODY_FULL].getHeight());
        images[BOTTOM].draw(drawX, drawY);

        font.print("" + currentValue, xPos + parent.getXPos()
                + images[BODY_EMPTY].getWidth() / 2 - 16, yPos
                + parent.getYPos() + width + 16, 0.8f, GLColor.WHITE);

        // Cycle the widget list and draw all
    }
}